跳到主要内容

How browsers work

在浏览网页时用户希望页面的内容能够快速加载且流畅交互。理解浏览器的工作原理有助于开发者了解该如何提升性能和感知性能。

概述

导致 Web 性能问题的原因主要有两种,

  1. 网络延迟。
  2. 大部分情况下的浏览器单线程执行。

网络延迟是将字节传输到计算机的时间。Web 性能优化需要做的就是使页面尽可能快地加载完成,或者至少看起来加载速度很快。

浏览器的单线程特性。也就是说,它们在执行一个任务之前会从头到尾完成一个任务,然后才会接受另一个任务。为了实现流畅的交互,渲染时间非常关键,我们需要尽可能和适当地减少主线程的责任,可以提高网页性能。

导航

它发生在以下情形:用户通过在地址栏输入一个 URL、点击一个链接、提交表单或者是其他的行为。

1️⃣ DNS 查询

浏览器向域名服务器发起 DNS 查询请求,最终得到一个 IP 地址。第一次请求之后,这个 IP 地址可能会被缓存一段时间,这样可以通过从缓存里面检索 IP 地址而不是再通过域名服务器进行查询来加速后续的请求。

每个主机名 (hostname) 在页面加载时通常只需要进行一次 DNS 查询。

2️⃣ TCP 握手

一旦获取到服务器 IP 地址,浏览器就会通过 TCP “三次握手”与服务器建立连接。

3️⃣ TLS 协商

对于通过 HTTPS 建立的安全连接,还需要另一次 "握手"。这种握手,或者说 TLS 协商,决定使用哪种密码对通信进行加密,验证服务器,并在开始实际数据传输前建立安全连接。

响应

一旦我们建立了和 web 服务器的连接,浏览器就会代表用户发送一个初始的 HTTP GET 请求,对于网站来说,这个请求通常是一个 HTML 文件。一旦服务器收到请求,它将使用相关的响应头和 HTML 的内容进行回复。

拥塞控制 / TCP 慢启动

初始请求的响应包含所接收数据的第一个字节,第一个内容分块通常是 14KB 的数据。

在传输过程中,TCP 包被分割成段。由于 TCP 保证了数据包的顺序,因此服务器在发送一定数量的分段后,必须从客户端接收一个 ACK 包的确认。

如果服务器在发送每个分段之后都等待 ACK,那么客户端将频繁地发送 ACK,并且可能会增加传输时间,即使在网络负载较低的情况下也是如此。

另一方面,一次发送过多的分段会导致在繁忙的网络中客户端无法接收分段并且长时间地只会持续发送 ACK,服务器必须不断重新发送分段的问题。

为了平衡传输分段的数量,TCP 慢启动算法用于逐渐增加传输数据量,直到确定最大网络带宽,并在网络负载较高时减少传输数据量。

解析

一旦浏览器收到第一个数据分块,它就可以开始解析收到的信息。“解析”是浏览器将通过网络接收的数据转换为 DOM 和 CSSOM 的步骤,通过渲染器在屏幕上将它们绘制成页面。

渲染

渲染步骤包括样式、布局、绘制,在某些情况下还包括合成。在解析步骤中创建的 CSSOM 树和 DOM 树组合成一个渲染树,然后用于计算每个可见元素的布局,然后将其绘制到屏幕上。在某些情况下,可以将内容提升到它们自己的层并进行合成,通过在 GPU 而不是 CPU 上绘制屏幕的一部分来提高性能,从而释放主线程。

交互

一旦主线程绘制页面完成,你会认为我们已经“准备好了”,但事实并非如此。如果加载包括正确延迟加载的 JavaScript,并且仅在 onload 事件触发后执行,那么主线程可能会忙于执行脚本,无法用于滚动、触摸和其他交互操作。

来源